package com.mzm.service;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Service;

import com.mzm.api.CategoryDto;
import com.mzm.dao.CategoryDao;
import com.mzm.dao.MediaInfoDao;
import com.mzm.dao.ProductInfoDao;
import com.mzm.dao.RecommendationDao;
import com.mzm.domain.Category;
import com.mzm.domain.MediaInfo;
import com.mzm.domain.ProductInfo;
import com.mzm.domain.Recommendation;

@Service("recommendationManagementService")
public class RecommendationManagementServiceImpl implements RecommendationManagementService {

	private static final Logger logger = LoggerFactory
			.getLogger(RecommendationManagementServiceImpl.class);

	@Resource
	private RecommendationDao recommendationDao;

	@Resource
	private MediaInfoDao mediaInfoDao;

	@Resource
	private CategoryDao categoryDao;

	@Resource
	private ProductInfoDao productInfoDao;

	@Required
	@Autowired
	public void setRecommendationDao(RecommendationDao recommendationDao) {
		this.recommendationDao = recommendationDao;
	}

	@Required
	@Autowired
	public void setMediaInfoDao(MediaInfoDao mediaInfoDao) {
		this.mediaInfoDao = mediaInfoDao;
	}

	@Required
	@Autowired
	public void setCategoryDao(CategoryDao categoryDao) {
		this.categoryDao = categoryDao;
	}

	@Required
	@Autowired
	public void setProductInfoDao(ProductInfoDao productInfoDao) {
		this.productInfoDao = productInfoDao;
	}

	@Override
	public Integer createRecommendation(Integer productId, Recommendation recommendation) {
		ProductInfo productInfo = productInfoDao.findById(productId, false);
		if (productInfo == null) {
			throw new IllegalArgumentException("No product with ID: " + productId);
		}
		recommendation.setProductInfo(productInfo);
		recommendationDao.create(recommendation);
		return recommendation.getId();
	}

	@Override
	public Integer createProductInfo(String categoryPath, ProductInfo productInfo) {
		Category category = categoryDao.getCategory(categoryPath);
		if (category == null) {
			throw new IllegalArgumentException("No such path: " + categoryPath);
		}
		productInfo.setCategory(category);
		productInfoDao.create(productInfo);
		return productInfo.getId();
	}

	@Override
	public void deleteProductInfo(Integer productInfoId) {
		productInfoDao.delete(productInfoId);
	}

	@Override
	public void deleteCategory(String path) {
		Category category = categoryDao.getCategory(path);
		if(category != null) {
			categoryDao.delete(category);
		}
		else {
			logger.warn("Attempting to delete non existing category: {}", path);
		}
	}

	@Override
	public Integer createCategory(String path) {
		logger.info("Creating new category: {}", path);
		String[] pathElements = PathUtils.parsePathElements(path);
		Category[] cats = new Category[pathElements.length];
		Integer id = null;
		for (int i = 0; i < pathElements.length; i++) {
			String elementPath = PathUtils.buildSubPathFromElements(pathElements, i);
			Category cat = categoryDao.getCategory(elementPath);
			if (cat != null) {
				cats[i] = cat;
				continue;
			}
			cats[i] = new Category(pathElements[i], cats[i - 1]);
			id = categoryDao.create(cats[i]);
		}
		return id;
	}

	@Override
	public CategoryDto getCategoryTree() {
		return categoryDao.getCategoryTree("/");
	}

	@Override
	public List<ProductInfo> getProductInfos(String path) {
		return productInfoDao.getProductInfos(path);
	}

	@Override
	public List<Recommendation> getRecommendations(String path) {
		return recommendationDao.getRecommendations(path);
	}

	@Override
	public List<Recommendation> getRecommendations(Integer productInfoId) {
		return recommendationDao.getRecommendations(productInfoId);
	}

	@Override
	public void deleteRecommendation(Integer recommendationId) {
		recommendationDao.delete(recommendationId);
	}

	@Override
	public void updateRecommendation(Recommendation r) {
		Recommendation rr = recommendationDao.findById(r.getId(), false);
		rr.setContent(r.getContent());
		rr.setCurrency(r.getCurrency());
		rr.setGrade(r.getGrade());
		rr.setGradeRange(r.getGradeRange());
		rr.setKeywords(r.getKeywords());
		rr.setPrice(r.getPrice());
		rr.setRecommenderName(r.getRecommenderName());
		rr.setRemarks(r.getRemarks());
		rr.setSheetNumber(r.getSheetNumber());
		recommendationDao.update(rr);
	}

	@Override
	public List<String> getAllCategoriesAsList() {
		return categoryDao.getAllCategoryNames();
	}

	@Override
	public void addMediaInfo(MediaInfo mediaInfo) {
		mediaInfoDao.create(mediaInfo);
		logger.info("Creating new MediaInfo named: {}", mediaInfo);
	}
}
